package com.wuye.common.util;


import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

public class StringUtil {

	final static String[]	SBC	= { "，", "。", "；", "“", "”", "？", "！", "（", "）", "：", "——", "、"};

	final static String[]	DBC	= { ",", ".", ";", "\"", "\"", "?", "!", "(", ")", ":", "_", ","};


	/**
	 * 去除字符串两端空格 如果字符串是空的返加null
	 * 
	 * @Param String
	 * @return String
	 */
	public static String trim(String str) {
		if (str == null)
			return null;

		str = str.trim();
		if (str.length() == 0)
			return null;
		return str;
	}


	public static String replaceStr(String str, String oldStr, String newStr) {
		int pos1 = 0;
		int pos2 = 0;
		StringBuffer retu = new StringBuffer();
		if (str != null && str.length() > 0) {
			for (pos2 = str.indexOf(oldStr, pos1); pos2 != -1; pos2 = str.indexOf(oldStr, pos1)) {
				retu.append(str.substring(pos1, pos2) + newStr);
				pos1 = pos2 + oldStr.length();
			}

			retu.append(str.substring(pos1));
		}
		return retu.toString();
	}


	/**
	 * 设置字符串首字母为大写
	 */
	public static String cap(String str) {
		if (str == null)
			return null;

		StringBuffer sb = new StringBuffer();
		sb.append(Character.toUpperCase(str.charAt(0)));
		sb.append(str.substring(1).toLowerCase());
		return sb.toString();
	}


	/**
	 * 判断字符串是否是包含a-z, A-Z, 0-9, _(下划线)
	 */
	public static boolean isWord(String str) {
		if (str == null)
			return false;

		char[] ch = str.toCharArray();
		int i;
		for (i = 0; i < str.length(); i++) {
			if ((!Character.isLetterOrDigit(ch[i])) && (ch[i] != '_'))
				return false;
		}
		return true;
	}


	/**
	 * 判断字符串是否数字
	 */
	public static boolean isNum(String str) {
		if (str == null || str.length() <= 0)
			return false;

		char[] ch = str.toCharArray();

		for (int i = 0; i < str.length(); i++)
			if (!Character.isDigit(ch[i]))
				return false;

		return true;
	}


	/**
	 * 判断字符串是否为实数
	 */
	public static boolean isNumEx(String str) {
		if (str == null || str.length() <= 0)
			return false;

		char[] ch = str.toCharArray();

		//判断第一个字符是否－号
		int index = 0;
		if(ch[0] == '-') index = 1;
		
		for (int i = index, comcount = 0; i < str.length(); i++) {
			if (!Character.isDigit(ch[i])) {
				if (ch[i] != '.')
					return false;

				else if (i == 0 || i == str.length() - 1)
					return false; // .12122 or 423423. is not a real number

				else if (++comcount > 1)
					return false; // 12.322.23 is not a real number
			}
		}
		return true;
	}


	/**
	 * examples: String str = (String)StringUtil.getStringStr("jfas12",1);
	 */
	public static Object getStringStr(String str, int index) {
		Vector reStr = new Vector();
		Object obj = getStringNumber(str, 0);

		if (obj == null) {
			if (index > 1)
				return null;
			return str;
		} else {
			for (int i = 0; i < ((Vector) obj).size(); i++) {
				int indexOfString = str.indexOf((String) (((Vector) obj).elementAt(i)));
				if (indexOfString != 0)
					reStr.addElement(str.substring(0, indexOfString));
				str = str.substring(indexOfString + ((String) (((Vector) obj).elementAt(i))).length());
			}
			if (str.length() != 0)
				reStr.addElement(str);
		}

		if (index <= 0)
			return reStr;
		if (index > reStr.size())
			return null;
		return reStr.elementAt(index - 1);
	}


	/**
	 * 得到字符串中的第index个数字字符串 example: int i =
	 * Integer.parseInt((String)StringUtil.getStringNumber("asjfdkla3.asfa4",1));
	 * return 1
	 */
	public static Object getStringNumber(String str, int index) {
		if (str == null)
			return null;

		char[] ch = str.toCharArray();
		int i;
		String tempStr = "";
		Vector returnNumber = new Vector();

		for (i = 0; i < str.length(); i++) {
			if (Character.isDigit(ch[i]))
				tempStr += ch[i];
			else {
				if (!tempStr.equals(""))
					returnNumber.addElement(tempStr);
				tempStr = "";
			}
		}

		if (!tempStr.equals(""))
			returnNumber.addElement(tempStr);

		if (returnNumber.isEmpty() || (index > returnNumber.size()))
			return null;
		else {
			if (index <= 0)
				return returnNumber;
			else
				return returnNumber.elementAt(index - 1);
		}
	}


	/**
	 * 替换字符串，sOld sNew的大小必须相同
	 */
	public static String replaceStrEq(String sReplace, String sOld, String sNew) {
		if (sReplace == null || sOld == null || sNew == null)
			return null;

		int iLen = sReplace.length();
		int iLenOldStr = sOld.length();
		int iLenNewStr = sNew.length();

		if (iLen <= 0 || iLenOldStr <= 0 || iLenNewStr <= 0)
			return sReplace;

		if (iLenOldStr != iLenNewStr)
			return sReplace;

		int[] iIndex = new int[iLen];
		iIndex[0] = sReplace.indexOf(sOld, 0);
		if (iIndex[0] == -1)
			return sReplace;

		int iIndexNum = 1;
		while (true) {
			iIndex[iIndexNum] = sReplace.indexOf(sOld, iIndex[iIndexNum - 1] + 1);
			if (iIndex[iIndexNum] == -1)
				break;
			iIndexNum++;
		}

		char[] caReplace = sReplace.toCharArray();
		char[] caNewStr = sNew.toCharArray();

		for (int i = 0; i < iIndexNum; i++) {
			for (int j = 0; j < iLenOldStr; j++) {
				caReplace[j + iIndex[i]] = caNewStr[j];
			}
		}
		return new String(caReplace);
	}


	/**
	 * 替换字符串
	 */
	public static String replaceStrEx(String sReplace, String sOld, String sNew) {
		if (sReplace == null || sOld == null || sNew == null)
			return null;

		int iLen = sReplace.length();
		int iLenOldStr = sOld.length();
		int iLenNewStr = sNew.length();

		if (iLen <= 0 || iLenOldStr <= 0 || iLenNewStr < 0)
			return sReplace;

		int[] iIndex = new int[iLen];
		iIndex[0] = sReplace.indexOf(sOld, 0);
		if (iIndex[0] == -1)
			return sReplace;

		int iIndexNum = 1;
		while (true) {
			iIndex[iIndexNum] = sReplace.indexOf(sOld, iIndex[iIndexNum - 1] + 1);
			if (iIndex[iIndexNum] == -1)
				break;
			iIndexNum++;
		}

		Vector vStore = new Vector();
		String sub = sReplace.substring(0, iIndex[0]);
		if (sub != null)
			vStore.add(sub);

		int i = 1;
		for (i = 1; i < iIndexNum; i++) {
			vStore.add(sReplace.substring(iIndex[i - 1] + iLenOldStr, iIndex[i]));
		}
		vStore.add(sReplace.substring(iIndex[i - 1] + iLenOldStr, iLen));

		StringBuffer sbReplaced = new StringBuffer("");
		for (i = 0; i < iIndexNum; i++) {
			sbReplaced.append(vStore.get(i) + sNew);
		}
		sbReplaced.append(vStore.get(i));

		return sbReplaced.toString();
	}


	/**
	 * 分隔字符串
	 */
	public static String[] splitStr(String sStr, String sSplitter) {
		if (sStr == null || sStr.length() <= 0 || sSplitter == null || sSplitter.length() <= 0)
			return null;

		String[] saRet = null;

		int[] iIndex = new int[sStr.length()];
		iIndex[0] = sStr.indexOf(sSplitter, 0);
		if (iIndex[0] == -1) {
			saRet = new String[1];
			saRet[0] = sStr;
			return saRet;
		}

		int iIndexNum = 1;
		while (true) {
			iIndex[iIndexNum] = sStr.indexOf(sSplitter, iIndex[iIndexNum - 1] + 1);
			if (iIndex[iIndexNum] == -1)
				break;
			iIndexNum++;
		}

		Vector vStore = new Vector();
		int iLen = sSplitter.length();
		int i = 0;
		String sub = null;

		for (i = 0; i < iIndexNum + 1; i++) {
			if (i == 0)
				sub = sStr.substring(0, iIndex[0]);
			else if (i == iIndexNum)
				sub = sStr.substring(iIndex[i - 1] + iLen, sStr.length());
			else
				sub = sStr.substring(iIndex[i - 1] + iLen, iIndex[i]);

			if (sub != null && sub.length() > 0)
				vStore.add(sub);
		}

		if (vStore.size() <= 0)
			return null;
		saRet = new String[vStore.size()];
		Enumeration e = vStore.elements();

		for (i = 0; e.hasMoreElements(); i++)
			saRet[i] = (String) e.nextElement();
		return saRet;
	}


	/**
	 * 以sContacter为分隔符连接字符串数组saStr
	 */
	public static String contactStr(String[] saStr, String sContacter) {
		if (saStr == null || saStr.length <= 0 || sContacter == null || sContacter.length() <= 0)
			return null;

		StringBuffer sRet = new StringBuffer("");
		for (int i = 0; i < saStr.length; i++) {
			if (i == saStr.length - 1)
				sRet.append(saStr[i]);
			else
				sRet.append(saStr[i] + sContacter);
		}
		return sRet.toString();
	}


	/**
	 * 转换整型数组为字符串
	 */
	public static String contactStr(int[] saStr, String sContacter) {
		if (saStr == null || saStr.length <= 0 || sContacter == null || sContacter.length() <= 0)
			return null;

		StringBuffer sRet = new StringBuffer("");
		for (int i = 0; i < saStr.length; i++) {
			if (i == saStr.length - 1)
				sRet.append(new Integer(saStr[i]));
			else
				sRet.append(new Integer(saStr[i]) + sContacter);
		}
		return sRet.toString();
	}


	/**
	 * 排序字符串数组
	 */
	public static String[] sortByLength(String[] saSource, boolean bAsc) {
		if (saSource == null || saSource.length <= 0)
			return null;

		int iLength = saSource.length;
		String[] saDest = new String[iLength];

		for (int i = 0; i < iLength; i++)
			saDest[i] = saSource[i];

		String sTemp = "";
		int j = 0, k = 0;

		for (j = 0; j < iLength; j++)
			for (k = 0; k < iLength - j - 1; k++) {
				if (saDest[k].length() > saDest[k + 1].length() && bAsc) {
					sTemp = saDest[k];
					saDest[k] = saDest[k + 1];
					saDest[k + 1] = sTemp;
				} else if (saDest[k].length() < saDest[k + 1].length() && !bAsc) {
					sTemp = saDest[k];
					saDest[k] = saDest[k + 1];
					saDest[k + 1] = sTemp;
				}
			}
		return saDest;
	}


	public static String compactStr(String str) {
		if (str == null)
			return null;

		if (str.length() <= 0)
			return "";

		String sDes = new String(str);
		int iBlanksAtStart = 0;
		int iLen = str.length();

		while (sDes.charAt(iBlanksAtStart) == ' ')
			if (++iBlanksAtStart >= iLen)
				break;

		String[] saDes = splitStr(sDes.trim(), " ");
		if (saDes == null)
			return null;

		int i = 0;
		for (i = 0; i < saDes.length; i++) {
			saDes[i] = saDes[i].trim();
		}

		sDes = contactStr(saDes, " ");
		StringBuffer sBlank = new StringBuffer("");
		for (i = 0; i < iBlanksAtStart; i++)
			sBlank.append(" ");

		return sBlank.toString() + sDes;
	}


	/**
	 * 转换sbctodbc
	 */
	public static String symbolSBCToDBC(String sSource) {
		if (sSource == null || sSource.length() <= 0)
			return sSource;

		int iLen = SBC.length < DBC.length ? SBC.length : DBC.length;
		for (int i = 0; i < iLen; i++)
			sSource = replaceStrEx(sSource, SBC[i], DBC[i]);
		return sSource;
	}


	/**
	 * 转换dbctosbc
	 */
	public static String symbolDBCToSBC(String sSource) {
		if (sSource == null || sSource.length() <= 0)
			return sSource;

		int iLen = SBC.length < DBC.length ? SBC.length : DBC.length;
		for (int i = 0; i < iLen; i++)
			sSource = replaceStrEx(sSource, DBC[i], SBC[i]);
		return sSource;
	}


	/**
	 * 判断是否email地址
	 */
	public static boolean isEmailUrl(String str) {
		if ((str == null) || (str.length() == 0))
			return false;

		if ((str.indexOf('@') > 0) && (str.indexOf('@') == str.lastIndexOf('@'))) {
			if ((str.indexOf('.') > 0) && (str.lastIndexOf('.') > str.indexOf('@'))) { return true; }
		}
		return false;
	}


	/**
	 * 判断是否email地址
	 */
	public static boolean isEmailAddress(String str) {
		if (str == null || str.length() <= 0)
			return false;

		int iCommonCount = 0;
		int iAltCount = 0;
		char[] chEmail = str.trim().toCharArray();

		for (int i = 0; i < chEmail.length; i++) {
			if (chEmail[i] == ' ')
				return false;

			else if (chEmail[i] == '.') {
				if (i == 0 || (i == chEmail.length - 1))
					return false;
			}

			else if (chEmail[i] == '@') {
				if (++iAltCount > 1 || i == 0 || i == chEmail.length - 1)
					return false;
			}
		}

		if (str.indexOf('.') < str.indexOf('@'))
			return false;
		return true;
	}


	/**
	 * 格式化日期
	 * 
	 * @param java.util.Date
	 *            date
	 * @param String
	 *            newFormat
	 * @return String example formatDate(date, "MMMM dd, yyyy") = July 20, 2000
	 */
	public static String formatDate(Date date, String newFormat) {
		if (date == null || newFormat == null)
			return null;

		java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat(newFormat);
		return formatter.format(date);
	}

	/**
	 * 将日期字符串转换成java.util.Date类型对象
	 * @param dateString 
	 * @param format     默认使用yyyy-MM-dd格式
	 * */
	public final static Date string2Date (String dateString , String format) {
		
		if (null == dateString || dateString.equals("")) 
			return null ;
		
		if (null == format || format.equals(""))
			format = "yyyy-MM-dd" ;  
		
		Date date = new Date ()  ;
		SimpleDateFormat formatter = new SimpleDateFormat(format) ;
		
		try {
			date = formatter.parse(dateString) ;
		} catch (Exception ex) {
			//ex.printStackTrace() ;
			date = null ;
		}
		
		return date ;
	}

	/**
	 * 去除字符串中的特殊字符和两端空格 如果字符串是空的返回null
	 * 
	 * @Param String
	 * @return String
	 */
	public static String clean(String s) {
		throw new RuntimeException("not support!");
//		String t;
//		if (s == null)
//			return null;
//		else
//			t = s;
//		t.replace('/', '／');
//		t.replace('<', '〈');
//		t.replace('>', '〉');
//		t.replace('"', '“');
//		t.replace(';', '；');
//		t.replace('\'', ' ');
//		t = StringUtil.replaceStrEx(t, "&", "*");
//		t = t.trim();
//		return t;
	}


	/**
	 * 将Null的String转换为空字符串
	 */
	public static String cEmpty(String s) {
		if (s == null)
			return "";
		return s;
	}


	/**
	 * 将空字符串转换为Null
	 */
	public static String cNull(String s) {
		if (s == null)
			return null;
		if (s.trim().length() == 0)
			return null;
		return s;
	}


	/**
	 * 如果s为空或Null, 则返回"NUll", 否则给s两边加上单引号返回。用在写数据库的时候。
	 */
	public static String nullString(String s) {
		if (s == null)
			return "Null";
		if (s.trim().length() == 0)
			return "Null";
		return "'" + s.trim() + "'";
	}


	public static String filterString(String s, String t) {
		String a = s;
		int i, j;
		j = t.length();
		while ((i = a.indexOf(t)) != -1) {
			a = a.substring(0, i - 1) + a.substring(i + j);
		}
		return a;
	}


	/**
	 * The method is used to get the bytes number of string
	 */
	public static int getTotalBytes(String srcString) {
		if (srcString == null)
			return 0;

		int result = 0;
		byte[] bytes = srcString.getBytes();
		for (int i = 0; i < bytes.length; i++) {
			if (bytes[i] != 0)
				result++;
			;
		}
		return result;
	}


	/**
	 * check the given string to see if it's null or empty string
	 */
	public static boolean isEmpty(String s) {
		if (s == null)
			return true;
		if (s.trim().length() == 0)
			return true;
		return false;
	}


	/**
	 * 检查是否匹配,可以带*
	 * 
	 * @param s1
	 * @param s2
	 * @return
	 */
	public static boolean isStrSuite(String ssub, String sparent) {
		ssub = ssub.trim();
		sparent = sparent.trim();

		String[] subarr = StringUtil.splitStr(ssub, " ");
		String[] pararr = StringUtil.splitStr(sparent, " ");

		return isStringArraySuite(subarr, pararr);
	}


	/**
	 * 检查是否匹配，可以带*
	 * 
	 * @param subarr
	 * @param pararr
	 * @return
	 */
	public static boolean isStringArraySuite(String[] subarr, String[] pararr) {

		if (subarr.length > pararr.length)
			return false;

		for (int i = 0; i < subarr.length; i++) {
			if (subarr[i].equals("*"))
				continue;
			if (pararr[i].equals("*"))
				continue;
			if (!subarr[i].equals(pararr[i]))
				return false;
		}
		return true;
	}


	public static String arrToString(Object arr) {
		String ret = "\nlen=" + Array.getLength(arr);
		for (int i = 0; i < Array.getLength(arr); i++) {
			ret = ret + "\nitem[" + i + "]=" + Array.get(arr, i);
		}
		return ret;
	}


	public static String mapToString(Map map) {
		String ret = "\nlen=" + map.keySet().size();
		Iterator it = map.keySet().iterator();
		while (it.hasNext()) {
			Object key = it.next();
			ret = ret + "\nkey[" + key + "]" + "  value=" + map.get(map.get(key));
		}

		return ret;
	}


	/**
	 * 判断是否为空指针或者空字符
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNotNullAndBlank(String str) {
		if (isNullOrBlank(str))
			return false;
		else
			return true;
	}


	/**
	 * 判断是否为空指针或者空字符
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNullOrBlank(String str) {
		if (isNull(str) || str.equals("") || str.equals("null"))
			return true;
		else
			return false;
	}


	/**
	 * 判断是否为空指针
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNull(String str) {
		if (str == null || str.trim().length() == 0) {
			return true;
		} else {
			return false;
		}
	}


	/**
	 * 判断是否为空指针
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNotNull(String str) {
		if (str == null || str.trim().length() == 0)
			return false;
		else if (str.trim().equalsIgnoreCase("null"))
			return false;
		else
			return true;
	}


	/**
	 * 将空指针转成空字符
	 * 
	 * @param str
	 * @return
	 */
	public static String ifNullToBlank(String str) {
		if (isNotNull(str) && !(str.trim().equals("null")))
			return str.trim();
		else
			return "";
	}


	public static String ifNullToBlank(Object obj) {
		String ret = "";
		String s = String.valueOf(obj);
		if (s == null || "".equals(s) || "null".equals(s) || "NULL".equals(s))
			ret = "";
		else
			ret = s;
		return ret;
	}


	public static final String escapeXML(String string) {
		//Check if the string is null or zero length -- if so, return
		//what was sent in.
		if (string == null || string.length() == 0) { return string; }
		char[] sArray = string.toCharArray();
		StringBuffer buf = new StringBuffer(sArray.length);
		char ch;
		for (int i = 0; i < sArray.length; i++) {
			ch = sArray[i];
			if (ch == '<') {
				buf.append("&lt;");
			} else if (ch == '&') {
				buf.append("&amp;");
			} else if (ch == '"') {
				buf.append("&quot;");
			} else {
				buf.append(ch);
			}
		}
		
		return buf.toString();
	}
	
	
	
	public static String[] splitStrWithBlank(String str,String delim) {
		if (str == null) {
			return null;
		}
		if (str.trim().equals("")) {
			return null;
		}
		List list = new ArrayList();
		int index = 0;
		while ((index = str.indexOf(delim)) >= 0) {
			list.add(str.substring(0, index));
			str = str.substring(index + 1, str.length());
		}
		list.add(str);
		String[] strs = new String[list.size()];
		list.toArray(strs);
		return strs;

	}

	public static char getCharAtPosDefaultZero(String s, int pos) {
		if (s==null) return '0';
		
		if (s.length() <= pos) return '0';
		return s.charAt(pos);
	}
	

	/**
	 * 设置字符串的制定位置（0表示第一个字符）字符。
	 * 如果字符串长度小于 位置+1 ，则首先给字符串 补充0
	 * 允许传入参数为null
	 * @param extend2
	 * @param pos_is_allow_sendback
	 * @param flag
	 * @return
	 */
	public static String setCharAtPosAppendZero(String s, int pos, char c) {
		if ( s ==null) s="";
		
		
		while ( pos > s.length() -1){
			s = s+'0';
		}
		
		String preString,afterString;
		
		if (pos == 0) preString="";
		else preString = s.substring(0,pos);
		
		if (pos == s.length()-1) afterString="";
		else afterString = s.substring( pos +1);
		
		return preString + c + afterString;
		

	}
	
//	public static void main(String[] arg){
//		System.out.println("s="+""+" pos="+5+" char="+'a' +"="+setCharAtPosAppendZero("",5,'a'));
//		
//		System.out.println("s="+"abcde"+" pos="+0+" char="+'7' +" ="+setCharAtPosAppendZero("abcde",0,'7'));
//		System.out.println("s="+"null"+" pos="+2+" char="+'a' +" ="+setCharAtPosAppendZero(null,2,'a'));
//		System.out.println("s="+"abcde"+" pos="+2+" char="+'x' +" ="+setCharAtPosAppendZero("abcde",2,'x'));
//		System.out.println("s="+"abcde"+" pos="+5+" char="+'x' +" ="+setCharAtPosAppendZero("abcde",5,'x'));
//		System.out.println("s="+"abcde"+" pos="+6+" char="+'x' +" ="+setCharAtPosAppendZero("abcde",5,'x'));
//	}


	/**
	 * @param stream
	 * @param encode
	 * @throws IOException
	 */
	public static String changeStreamToString(InputStream stream, String encode) throws IOException {
		
		byte[] b100k=new byte[200000];
		
		int pos=0;
		while(true){
			int len = stream.read(b100k,pos,b100k.length-pos);
			if  (len<=0) break;
			else pos = pos+len;
		}
		
		if (pos >= b100k.length-1) {
			throw new IOException("ERROR:The stream size is more than "+b100k.length+" bytes");
		}
		
		return new String(b100k,0,pos,encode);
	}
	
//	public static String fillBlank(String s,int n,boolean isLeft){
//		if (s.length()>=n) return s;
//		for (int i=s.length();i<n;i++){
//			if (isLeft){
//				s = " "+s;
//			}else {
//				s = s + " ";
//			}
//		}
//		return s;
//	}
	
	
	public static String replaceBlanks (String s) {
		
		Pattern ptn = Pattern.compile ("\\t|\r|\n");
		Matcher mt = ptn.matcher(s) ;
		return mt.replaceAll("") ;
		
	}
	
	public static String replaceScriptKeyword (String src ) {
		
		Pattern ptn = Pattern.compile ("<script>");
		Matcher mt = ptn.matcher(src) ;
		src = mt.replaceAll("<scriptValue>") ;
		
		ptn =Pattern.compile("</script>") ;
		mt = ptn.matcher(src) ;
		
		return mt.replaceAll("</scriptValue>") ;
		
	}
	
	public static String replaceScriptKeyWords(String s) {
		
		Pattern ptn = Pattern.compile("") ;
		return "" ;
	}
	/**
	 * 
	 * @param version1
	 * @param version2
	 * @return 1 0 -1
	 */
//	public static int compareVersion(String version1,String version2){
//		StringTokenizer st1 = new StringTokenizer(version1,".");
//		StringTokenizer st2 = new StringTokenizer(version2,".");
//		
//		ArrayList al1 = new ArrayList();
//		ArrayList al2 = new ArrayList();
//		
//		while (st1.hasMoreTokens()){
//			al1.add(st1.nextToken());
//		}
//		while (st2.hasMoreTokens()){
//			al2.add(st2.nextToken());
//		}
//		
//		int size1=al1.size();
//		int size2=al2.size();
//		
//		for (int i=0;i<size1 && i<size2; i++){
//			int v1 = Integer.parseInt((String)al1.get(i));
//			int v2 = Integer.parseInt((String)al2.get(i));
//			
//			if (v1>v2) return 1;
//			if (v1<v2) return -1;
//		}
//		
//		if (size1>size2) return 1;
//		if (size1<size2) return -1;
//		return 0;
//	}
	
    /**
     * 计算String的native字符串长度
     *
     * @return java.lang.String
     */
    public static int nativeLength(String s) {
        if (s == null || s.length() == 0) {
            return 0;
        }
        int length = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) >= 0x100) {
                length = length + 3;
            } else {
                length++;
            }
        }
        return length;
    }
    
    public final static int MAX_VARCHAR_PREPARE_LENGTH = 1000;
    
	/**
	 * 2005-11-7 添加对oracle数据库中长字符串字段的处理，
	 * 解决oracle jdbc的setString超过1280字节时的异常。
	 * @param aValueList
	 * @param aDataTypes
	 * @return
	 */
	public static String varcharSQLString(List retList, String value){
		if(value != null && (nativeLength(value) > MAX_VARCHAR_PREPARE_LENGTH)){
			
			// modify by wangkq 2007/4/4 原来将字符串进行拆分的算法不正确，采用DataUtil.nativeLength中获取
			// 字符串长度方法来进行字符串分割
			String sql = "?";
			StringBuffer buff = new StringBuffer("");
			int len = 0;
			int sLen = value.length();
			for (int i=0; i<sLen; i++) {
				char c = value.charAt(i);
	            if (c >= 0x100) {
	            	if ((len + 3) > MAX_VARCHAR_PREPARE_LENGTH) {
	            		retList.add(buff.toString());
	            		sql = sql.concat(" || ?");
	            		buff = new StringBuffer(String.valueOf(c));
	            		len = 3;
	            		continue;
	            	}
	                len = len + 3;
	            } else {
	                len++;
	            }
				buff.append(c);
				if (len == MAX_VARCHAR_PREPARE_LENGTH){
					retList.add(buff.toString());
            		if (i<(sLen-1))
            			sql = sql.concat(" || ?");
            		buff = new StringBuffer("");
            		len = 0;
				}
			}
			if (len > 0) {
				retList.add(buff.toString());
			}

			return sql;
		}else{
			retList.add(value);
			return null;
		}
	}
    
	
    
	public static void main(String[] arg){
//		System.out.println(compareVersion("1.1.1","1.1.2"));
//		System.out.println(compareVersion("1.1.2","1.1.1"));
//		
//		System.out.println(compareVersion("1123.1.2","99.1.1"));
//		
//		System.out.println(compareVersion("1123.1.2","1123.1.2.0"));
//		
//		System.out.println(compareVersion(".","1.1.1"));
		String aaaaaa = "123435";
		System.out.println(StringUtil.isNumEx(aaaaaa));
		Object aaa = new Object();
		System.out.println(aaa instanceof String);
	}
	
	
	


	private static final String EmailPattern = "^[_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,3})$";

	private static final transient Pattern emailPattern;

	private static final String DEFAULT_PREFIX = "${"; //add by chugh 2006/12/26

	private static final String DEFAULT_SUFFIX = "}"; //add by chugh 2006/12/26

//	final static String[] SBC = {
//		"，",
//		"。",
//		"；",
//		"“",
//		"”",
//		"？",
//		"！",
//		"（",
//		"）",
//		"：",
//		"——",
//		"、"
//	};
//
//	final static String[] DBC = {
//		",",
//		".",
//		";",
//		"\"",
//		"\"",
//		"?",
//		"!",
//		"(",
//		")",
//		":",
//		"_",
//		","
//	};

	static {
		emailPattern = Pattern.compile(EmailPattern);
	}

	/**
	 * 因为不需要实例，所以构造函数为私有<BR>
	 * 参见Singleton模式<BR>
	 *
	 * Only one instance is needed,so the default constructor is private<BR>
	 * Please refer to singleton design pattern.
	 */
	private StringUtil() {
		super();
	}

	/**
	 * 判断字符串是否是包含a-z, A-Z, 0-9, _(下划线)
	 */
//	public static boolean isWord(String str) {
//		if (str == null) {
//			return false;
//		}
//
//		char[] ch = str.toCharArray();
//		int i;
//		for (i = 0; i < str.length(); i++) {
//			if ((!Character.isLetterOrDigit(ch[i])) && (ch[i] != '_')) {
//				return false;
//			}
//		}
//		return true;
//	}

	/**
	 * 判断字符串是否为实数
	 */
//	public static boolean isNumEx(String str) {
//		if ((str == null) || (str.length() <= 0)) {
//			return false;
//		}
//		//TODO
//
//		char[] ch = str.toCharArray();
//
//		for (int i = 0, comcount = 0; i < str.length(); i++) {
//			if (!Character.isDigit(ch[i])) {
//				if (ch[i] != '.') {
//					return false;
//				}
//				else if ((i == 0) || (i == str.length() - 1)) {
//					return false; // .12122 or 423423. is not a real number
//				}
//				else if (++comcount > 1) {
//					return false; // 12.322.23 is not a real number
//				}
//			}
//		}
//		return true;
//	}

	/**
	 * 得到字符串中的第index个数字字符串 example: int i =
	 * Integer.parseInt((String)StringUtil.getStringNumber("asjfdkla3.asfa4",1));
	 * return 1
	 */
//	public static Object getStringNumber(String str, int index) {
//		if (str == null) {
//			return null;
//		}
//
//		char[] ch = str.toCharArray();
//		int i;
//		String tempStr = "";
//		Vector returnNumber = new Vector();
//
//		for (i = 0; i < str.length(); i++) {
//			if (Character.isDigit(ch[i])) {
//				tempStr += ch[i];
//			}
//			else {
//				if (!tempStr.equals("")) {
//					returnNumber.addElement(tempStr);
//				}
//				tempStr = "";
//			}
//		}
//
//		if (!tempStr.equals("")) {
//			returnNumber.addElement(tempStr);
//		}
//
//		if (returnNumber.isEmpty() || (index > returnNumber.size())) {
//			return null;
//		}
//		else {
//			if (index <= 0) {
//				return returnNumber;
//			}
//			else {
//				return returnNumber.elementAt(index - 1);
//			}
//		}
//	}

	/**
	 * 排序字符串数组
	 */
//	public static String[] sortByLength(String[] saSource, boolean bAsc) {
//		if ((saSource == null) || (saSource.length <= 0)) {
//			return null;
//		}
//
//		int iLength = saSource.length;
//		String[] saDest = new String[iLength];
//
//		for (int i = 0; i < iLength; i++) {
//			saDest[i] = saSource[i];
//		}
//
//		String sTemp = "";
//		int j = 0, k = 0;
//
//		for (j = 0; j < iLength; j++) {
//			for (k = 0; k < iLength - j - 1; k++) {
//				if ((saDest[k].length() > saDest[k + 1].length()) && bAsc) {
//					sTemp = saDest[k];
//					saDest[k] = saDest[k + 1];
//					saDest[k + 1] = sTemp;
//				}
//				else if ((saDest[k].length() < saDest[k + 1].length()) && !bAsc) {
//					sTemp = saDest[k];
//					saDest[k] = saDest[k + 1];
//					saDest[k + 1] = sTemp;
//				}
//			}
//		}
//		return saDest;
//	}

	/**
	 * 转换sbctodbc
	 */
//	public static String symbolSBCToDBC(String sSource) {
//		if ((sSource == null) || (sSource.length() <= 0)) {
//			return sSource;
//		}
//
//		int iLen = SBC.length < DBC.length ? SBC.length : DBC.length;
//		for (int i = 0; i < iLen; i++) {
//			sSource = StringUtils.replace(sSource, SBC[i], DBC[i]);
//		}
//		return sSource;
//	}

	/**
	 * 转换dbctosbc
	 */
//	public static String symbolDBCToSBC(String sSource) {
//		if ((sSource == null) || (sSource.length() <= 0)) {
//			return sSource;
//		}
//
//		int iLen = SBC.length < DBC.length ? SBC.length : DBC.length;
//		for (int i = 0; i < iLen; i++) {
//			sSource = StringUtils.replace(sSource, DBC[i], SBC[i]);
//		}
//		return sSource;
//	}

	/**
	 * 判断是否email地址
	 */
//	public static boolean isEmailAddress(String str) {
//		if (StringUtils.isEmpty(str)) {
//			return false;
//		}
//
//		return emailPattern.matcher(str).matches();
//	}

	/**
	 * 如果s为空或Null, 则返回"Null", 否则给s两边加上单引号返回。用在写数据库的时候。
	 */
//	public static String quoteNullString(String s) {
//		if (s == null) {
//			return "Null";
//		}
//		if (s.trim().length() == 0) {
//			return "Null";
//		}
//		return "'" + s.trim() + "'";
//	}

	/**
	 *
	 *
	 * @param s
	 * @param pos
	 * @return
	 */
//	public static char getCharAtPosDefaultZero(String s, int pos) {
//		if (s == null) {
//			return '0';
//		}
//
//		if (s.length() <= pos) {
//			return '0';
//		}
//		return s.charAt(pos);
//
//		//		FIXME
//	}

	/**
	 * 设置字符串的制定位置（0表示第一个字符）字符。
	 * 如果字符串长度小于 位置+1 ，则首先给字符串 补充0
	 * 允许传入参数为null
	 * @param extend2
	 * @param pos_is_allow_sendback
	 * @param flag
	 * @return
	 */
//	public static String setCharAtPosAppendZero(String s, int pos, char c) {
//		if (s == null) {
//			s = "";
//		}
//
//		while (pos > s.length() - 1) {
//			s = s + '0';
//		}
//
//		String preString, afterString;
//
//		if (pos == 0) {
//			preString = "";
//		}
//		else {
//			preString = s.substring(0, pos);
//		}
//
//		if (pos == s.length() - 1) {
//			afterString = "";
//		}
//		else {
//			afterString = s.substring(pos + 1);
//		}
//
//		return preString + c + afterString;
//
//	}

	/**
	 * 在指定字符串的左面或者右面，添加指定数量的空格。<BR>
	 *
	 * @param s
	 * @param n
	 * @param isLeft
	 * @return
	 */
	public static String fillBlank(String s, int n, boolean isLeft) {

		if (n < 0) {
			return s;
		}

		if (StringUtils.isEmpty(s)) {
			return StringUtils.rightPad("", n, " ");
		}

		if (s.length() >= n) {
			return s;
		}
		if (isLeft) {
			return StringUtils.leftPad(s, n, " ");
		}
		else {
			return StringUtils.rightPad(s, n, " ");
		}
	}

	/**
	 * 比较两个版本的大小。<BR>
	 *
	 * @param version1
	 * @param version2
	 * @return 1 0 -1
	 */	
	public static int compareVersion(String version1, String version2) {
		StringTokenizer st1 = new StringTokenizer(version1, ".");
		StringTokenizer st2 = new StringTokenizer(version2, ".");

		ArrayList al1 = new ArrayList();
		ArrayList al2 = new ArrayList();

		while (st1.hasMoreTokens()) {
			al1.add(st1.nextToken());
		}
		while (st2.hasMoreTokens()) {
			al2.add(st2.nextToken());
		}

		int size1 = al1.size();
		int size2 = al2.size();

		for (int i = 0; (i < size1) && (i < size2); i++) {
			int v1 = Integer.parseInt((String) al1.get(i));
			int v2 = Integer.parseInt((String) al2.get(i));

			if (v1 > v2) {
				return 1;
			}
			if (v1 < v2) {
				return -1;
			}
		}

		if (size1 > size2) {
			return 1;
		}
		if (size1 < size2) {
			return -1;
		}
		return 0;
	}

	/**
	 * Delete any character in a given string.
	 * @param charsToDelete a set of characters to delete.
	 * E.g. "az\n" will delete 'a's, 'z's and new lines.
	 */
	public static String deleteAny(String inString, String charsToDelete) {
		if ((inString == null) || (charsToDelete == null)) {
			return inString;
		}

		StringBuffer out = new StringBuffer();
		for (int i = 0; i < inString.length(); i++) {
			char c = inString.charAt(i);
			if (charsToDelete.indexOf(c) == -1) {
				out.append(c);
			}
		}
		return out.toString();
	}

	//---------------------------------------------------------------------
	// Convenience methods for working with formatted Strings
	//---------------------------------------------------------------------

	/**
	 * Quote the given String with single quotes.
	 * @param str the input String (e.g. "myString")
	 * @return the quoted String (e.g. "'myString'"),
	 * or <code>null<code> if the input was <code>null</code>
	 */
	public static String quote(String str) {
		return (str != null ? "'" + str + "'" : null);
	}

	/**
	 * Turn the given Object into a String with single quotes
	 * if it is a String; keeping the Object as-is else.
	 * @param obj the input Object (e.g. "myString")
	 * @return the quoted String (e.g. "'myString'"),
	 * or the input object as-is if not a String
	 */
	public static Object quoteIfString(Object obj) {
		return (obj instanceof String ? quote((String) obj) : obj);
	}

	/**
	 * Unqualify a string qualified by a '.' dot character. For example,
	 * "this.name.is.qualified", returns "qualified".
	 * @param qualifiedName the qualified name
	 */
	public static String unqualify(String qualifiedName) {
		return unqualify(qualifiedName, '.');
	}

	/**
	 * Unqualify a string qualified by a separator character. For example,
	 * "this:name:is:qualified" returns "qualified" if using a ':' separator.
	 * @param qualifiedName the qualified name
	 * @param separator the separator
	 */
	public static String unqualify(String qualifiedName, char separator) {
		return qualifiedName.substring(qualifiedName.lastIndexOf(separator) + 1);
	}

	/**
	 * Parse the given locale string into a <code>java.util.Locale</code>.
	 * This is the inverse operation of Locale's <code>toString</code>.
	 * @param localeString the locale string, following
	 * <code>java.util.Locale</code>'s toString format ("en", "en_UK", etc).
	 * Also accepts spaces as separators, as alternative to underscores.
	 * @return a corresponding Locale instance
	 */
	public static Locale parseLocaleString(String localeString) {
		String[] parts = tokenizeToStringArray(localeString, "_ ", false, false);
		String language = (parts.length > 0 ? parts[0] : "");
		String country = (parts.length > 1 ? parts[1] : "");
		String variant = (parts.length > 2 ? parts[2] : "");
		return (language.length() > 0 ? new Locale(language, country, variant) : null);
	}

	/**
	 * Remove duplicate Strings from the given array.
	 * Also sorts the array, as it uses a TreeSet.
	 * @param array the String array
	 * @return an array without duplicates, in natural sort order
	 */
	public static String[] removeDuplicateStrings(String[] array) {
		if (ArrayUtils.isEmpty(array)) {
			return array;
		}
		Set set = new TreeSet();
		for (int i = 0; i < array.length; i++) {
			set.add(array[i]);
		}
		return ArrayUtil.getStringArrayValues(set);
	}

	/**
	 * Take an array Strings and split each element based on the given delimiter.
	 * A <code>Properties</code> instance is then generated, with the left of the
	 * delimiter providing the key, and the right of the delimiter providing the value.
	 * <p>Will trim both the key and value before adding them to the
	 * <code>Properties</code> instance.
	 * @param array the array to process
	 * @param delimiter to split each element using (typically the equals symbol)
	 * @return a <code>Properties</code> instance representing the array contents,
	 * or <code>null</code> if the array to process was null or empty
	 */
	public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter) {
		return splitArrayElementsIntoProperties(array, delimiter, null);
	}

	/**
	 * Take an array Strings and split each element based on the given delimiter.
	 * A <code>Properties</code> instance is then generated, with the left of the
	 * delimiter providing the key, and the right of the delimiter providing the value.
	 * <p>Will trim both the key and value before adding them to the
	 * <code>Properties</code> instance.
	 * @param array the array to process
	 * @param delimiter to split each element using (typically the equals symbol)
	 * @param charsToDelete one or more characters to remove from each element
	 * prior to attempting the split operation (typically the quotation mark
	 * symbol), or <code>null</code> if no removal should occur
	 * @return a <code>Properties</code> instance representing the array contents,
	 * or <code>null</code> if the array to process was null or empty
	 */
	public static Properties splitArrayElementsIntoProperties(String[] array, String delimiter, String charsToDelete) {

		if ((array == null) || (array.length == 0)) {
			return null;
		}

		Properties result = new Properties();
		for (int i = 0; i < array.length; i++) {
			String element = array[i];
			if (charsToDelete != null) {
				element = deleteAny(array[i], charsToDelete);
			}
			String[] splittedElement = StringUtils.split(element, delimiter);
			if (splittedElement == null) {
				continue;
			}
			result.setProperty(splittedElement[0].trim(), splittedElement[1].trim());
		}
		return result;
	}

	/**
	 * Tokenize the given String into a String array via a StringTokenizer.
	 * Trims tokens and omits empty tokens.
	 * <p>The given delimiters string is supposed to consist of any number of
	 * delimiter characters. Each of those characters can be used to separate
	 * tokens. A delimiter is always a single character; for multi-character
	 * delimiters, consider using <code>delimitedListToStringArray</code>
	 * @param str the String to tokenize
	 * @param delimiters the delimiter characters, assembled as String
	 * (each of those characters is individually considered as delimiter).
	 * @return an array of the tokens
	 * @see java.util.StringTokenizer
	 * @see java.lang.String#trim
	 * @see #delimitedListToStringArray
	 */
	public static String[] tokenizeToStringArray(String str, String delimiters) {
		return tokenizeToStringArray(str, delimiters, true, true);
	}

	/**
	 * Tokenize the given String into a String array via a StringTokenizer.
	 * <p>The given delimiters string is supposed to consist of any number of
	 * delimiter characters. Each of those characters can be used to separate
	 * tokens. A delimiter is always a single character; for multi-character
	 * delimiters, consider using <code>delimitedListToStringArray</code>
	 * @param str the String to tokenize
	 * @param delimiters the delimiter characters, assembled as String
	 * (each of those characters is individually considered as delimiter)
	 * @param trimTokens trim the tokens via String's <code>trim</code>
	 * @param ignoreEmptyTokens omit empty tokens from the result array
	 * (only applies to tokens that are empty after trimming; StringTokenizer
	 * will not consider subsequent delimiters as token in the first place).
	 * @return an array of the tokens
	 * @see java.util.StringTokenizer
	 * @see java.lang.String#trim
	 * @see #delimitedListToStringArray
	 */
	public static String[] tokenizeToStringArray(String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {

		StringTokenizer st = new StringTokenizer(str, delimiters);
		List tokens = new ArrayList();
		while (st.hasMoreTokens()) {
			String token = st.nextToken();
			if (trimTokens) {
				token = token.trim();
			}
			if (!ignoreEmptyTokens || (token.length() > 0)) {
				tokens.add(token);
			}
		}
		return ArrayUtil.getStringArrayValues(tokens);
	}

	/**
	 * Convert a CSV list into an array of Strings.
	 * @param str CSV list
	 * @return an array of Strings, or the empty array if s is null
	 */
	public static String[] commaDelimitedListToStringArray(String str) {
		return StringUtils.split(str, ",");
	}

	/**
	 * Convenience method to convert a CSV string list to a set.
	 * Note that this will suppress duplicates.
	 * @param str CSV String
	 * @return a Set of String entries in the list
	 */
	public static Set commaDelimitedListToSet(String str) {
		Set set = new TreeSet();
		String[] tokens = commaDelimitedListToStringArray(str);
		for (int i = 0; i < tokens.length; i++) {
			set.add(tokens[i]);
		}
		return set;
	}

	/**
	 * Convenience method to return a String array as a delimited (e.g. CSV)
	 * String. E.g. useful for toString() implementations.
	 * @param arr array to display. Elements may be of any type (toString
	 * will be called on each element).
	 * @param delim delimiter to use (probably a ",")
	 */
	public static String arrayToDelimitedString(Object[] arr, String delim) {
		if (arr == null) {
			return "";
		}

		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < arr.length; i++) {
			if (i > 0) {
				sb.append(delim);
			}
			sb.append(arr[i]);
		}
		return sb.toString();
	}

	/**
	 * Convenience method to return a Collection as a delimited (e.g. CSV)
	 * String. E.g. useful for toString() implementations.
	 * @param coll Collection to display
	 * @param delim delimiter to use (probably a ",")
	 * @param prefix string to start each element with
	 * @param suffix string to end each element with
	 */
	public static String collectionToDelimitedString(Collection coll, String delim, String prefix, String suffix) {
		if (coll == null) {
			return "";
		}

		StringBuffer sb = new StringBuffer();
		Iterator it = coll.iterator();
		int i = 0;
		while (it.hasNext()) {
			if (i > 0) {
				sb.append(delim);
			}
			sb.append(prefix).append(it.next()).append(suffix);
			i++;
		}
		return sb.toString();
	}

	/**
	 * Convenience method to return a Collection as a delimited (e.g. CSV)
	 * String. E.g. useful for toString() implementations.
	 * @param coll Collection to display
	 * @param delim delimiter to use (probably a ",")
	 */
	public static String collectionToDelimitedString(Collection coll, String delim) {
		return collectionToDelimitedString(coll, delim, "", "");
	}

	/**
	 * Convenience method to return a String array as a CSV String.
	 * E.g. useful for toString() implementations.
	 * @param arr array to display. Elements may be of any type (toString
	 * will be called on each element).
	 */
	public static String arrayToCommaDelimitedString(Object[] arr) {
		return arrayToDelimitedString(arr, ",");
	}

	/**
	 * Convenience method to return a Collection as a CSV String.
	 * E.g. useful for toString() implementations.
	 * @param coll Collection to display
	 */
	public static String collectionToCommaDelimitedString(Collection coll) {
		return collectionToDelimitedString(coll, ",");
	}

	/**
	 * replace tokens in a string that starts with "${" and ends with "}";
	 * add by chugh 2006/12/26
	 *
	 * @param src source string that contains tokens;
	 * @param props properties;
	 * @return String with tokens replaces;
	 */
	public static String replace(String src, Map props) {
		return replace(src, DEFAULT_PREFIX, DEFAULT_SUFFIX, props);
	}

	/**
	 * replace symbols in a string;
	 * add by chugh 2006/12/26
	 *
	 *
	 * @param src
	 * @param prefix
	 * @param suffix
	 * @param props
	 * @return a String with symbol replaced;
	 */
	public static String replace(String src, String prefix, String suffix, Map props) {
		int index1;
		int index2;
		int len1 = prefix.length();
		int len2 = suffix.length();

		StringBuffer sb = new StringBuffer();

		index1 = src.indexOf(prefix);
		while (index1 >= 0) {
			sb.append(src.substring(0, index1));
			src = src.substring(index1 + len1);
			if (src.startsWith(prefix)) {
				sb.append(prefix);
				break;
			}
			else {
				index2 = src.indexOf(suffix);
				if (index2 >= 0) {
					String t = src.substring(0, index2);
					Object o = props.get(t);
					String sp = (o == null ? "" : o.toString());
					sb.append(sp);
					src = src.substring((index2 + len2));
					index1 = src.indexOf(prefix);
				}
				else {
					sb.append(prefix);
					break;
				}
			}
		}
		sb.append(src);
		return new String(sb);
	}

//	/**
//	 * 判断是否为空指针或者空字符
//	 *
//	 * Add by liuxj
//	 *
//	 * @param str
//	 * @return
//	 */
//	public static boolean isNotNullAndBlank(String str) {
//		if (isNullOrBlank(str)) {
//			return false;
//		}
//		else {
//			return true;
//		}
//	}
//
//	/**
//	 * 判断是否为空指针或者空字符
//	 *
//	 * Add by liuxj
//	 *
//	 * @param str
//	 * @return
//	 */
//	public static boolean isNullOrBlank(String str) {
//		if (isNull(str) || str.equals("") || str.equals("null")) {
//			return true;
//		}
//		else {
//			return false;
//		}
//	}
//
//	/**
//	 * 判断是否为空指针
//	 *
//	 * Add by liuxj
//	 *
//	 * @param str
//	 * @return
//	 */
//	public static boolean isNull(String str) {
//		if ((str == null) || (str.trim().length() == 0)) {
//			return true;
//		}
//		else {
//			return false;
//		}
//	}
//
//	/**
//	 * 判断是否为空指针
//	 *
//	 * Add by liuxj
//	 *
//	 * @param str
//	 * @return
//	 */
//	public static boolean isNotNull(String str) {
//		if ((str == null) || (str.trim().length() == 0)) {
//			return false;
//		}
//		else if (str.trim().equalsIgnoreCase("null")) {
//			return false;
//		}
//		else {
//			return true;
//		}
//	}
//
//	/**
//	 * 将空指针转成空字符
//	 *
//	 * Add by liuxj
//	 *
//	 * @param str
//	 * @return
//	 */
//	public static String ifNullToBlank(String str) {
//		if (isNotNull(str) && !(str.trim().equals("null"))) {
//			return str.trim();
//		}
//		else {
//			return "";
//		}
//	}
//
//	/**
//	 * 将空指针转成空字符
//	 *
//	 * Add by liuxj
//	 *
//	 * @param obj
//	 * @return
//	 */
//	public static String ifNullToBlank(Object obj) {
//		String ret = "";
//		String s = String.valueOf(obj);
//		if ((s == null) || "".equals(s) || "null".equals(s) || "NULL".equals(s)) {
//			ret = "";
//		}
//		else {
//			ret = s;
//		}
//		return ret;
//	}

	/**
	 * Tests if a string contains stars or question marks
	 * @param input a String which one wants to test for containing wildcard
	 * @return true if the string contains at least a star or a question mark
	 */
	public static boolean hasWildcards(String input) {
		return (StringUtils.contains(input, "*") || StringUtils.contains(input, "?"));
	}

	/**
	 * 用来判断指定的词是否与指定的字符串数组中的一个匹配。支持'*'和'?'。<BR>
	 *
	 * This method is used to judge whether one of the string array match the specified word.<BR>
	 *
	 * @param r_Keyword
	 * @param r_WildcardMatcher
	 * @param r_CaseSensitive
	 * @return
	 */
	public static boolean isWildcardMatchOne(String r_Keyword, String[] r_WildcardMatcher, boolean r_CaseSensitive) {
		if (null == r_WildcardMatcher) {
			return true;
		}

		for (int i = 0; i < r_WildcardMatcher.length; i++) {
			String t_WildCardMatcher = r_WildcardMatcher[i];

			if (isWildcardMatch(r_Keyword, t_WildCardMatcher, r_CaseSensitive)) {
				return true;
			}
		}

		return false;
	}

	/**
	 * 用来判断指定的词是否与指定的字符串数组中的所有匹配。支持'*'和'?'。<BR>
	 *
	 * This method is used to judge whether all the string arrays match the specified word.<BR>
	 *
	 * @param r_Keyword
	 * @param r_WildcardMatcher
	 * @param r_CaseSensitive
	 * @return
	 */
	public static boolean isWildcardMatchAll(String r_Keyword, String[] r_WildcardMatcher, boolean r_CaseSensitive) {
		if (null == r_WildcardMatcher) {
			return true;
		}

		for (int i = 0; i < r_WildcardMatcher.length; i++) {
			String t_WildCardMatcher = r_WildcardMatcher[i];

			if (!isWildcardMatch(r_Keyword, t_WildCardMatcher, r_CaseSensitive)) {
				return false;
			}
		}

		return true;
	}

	/**
	 * 用来判断是否匹配。<BR>
	 * 可以使用'*'和'?'来进行匹配。<BR>
	 *
	 * This method is used match 2 strings wildly.<BR>
	 * The char of '*' and '?' can be used.<BR>
	 *
	 * For Example: isWildcardMatch("username", "u*er*",true) --> true isWildcardMatch("username", "u?er*",true) -->
	 * true isWildcardMatch("username", "u*ter*") --> false isWildcardMatch("username", "U*er*",true) --> false
	 *
	 * @param r_Keyword
	 * @param r_WildcardMatcher
	 * @return
	 */
	public static boolean isWildcardMatch(String r_Keyword, String r_WildcardMatcher) {
		return isWildcardMatch(r_Keyword, r_WildcardMatcher, true);
	}

	/**
	 * 用来判断是否匹配。<BR>
	 * 可以使用'*'和'?'来进行匹配。<BR>
	 *
	 * This method is used match 2 strings wildly.<BR>
	 * The char of '*' and '?' can be used.<BR>
	 *
	 * For Example: isWildcardMatch("username", "u*er*",true) --> true isWildcardMatch("username", "u?er*",true) -->
	 * true isWildcardMatch("username", "u*ter*",true) --> false isWildcardMatch("username", "U*er*",true) --> false
	 * isWildcardMatch("username", "U*er*",false) --> true
	 *
	 * @param r_Keyword
	 * @param r_WildcardMatcher
	 * @param r_CaseSensitive
	 * @return
	 */
	public static boolean isWildcardMatch(String r_Keyword, String r_WildcardMatcher, boolean r_CaseSensitive) {
		if ((r_Keyword == null) && (r_WildcardMatcher == null)) {
			return true;
		}
		if ((r_Keyword == null) || (r_WildcardMatcher == null)) {
			return false;
		}
		if (!r_CaseSensitive) {
			r_Keyword = r_Keyword.toLowerCase();
			r_WildcardMatcher = r_WildcardMatcher.toLowerCase();
		}
		String[] t_SplitValues = splitOnTokens(r_WildcardMatcher);
		boolean t_Chars = false;
		int t_Index = 0;
		int t_WildIndex = 0;
		Stack t_BackStack = new Stack();

		// loop around a backtrack stack, to handle complex * matching
		do {
			if (t_BackStack.size() > 0) {
				int[] array = (int[]) t_BackStack.pop();
				t_WildIndex = array[0];
				t_Index = array[1];
				t_Chars = true;
			}

			// loop whilst tokens and text left to process
			while (t_WildIndex < t_SplitValues.length) {

				if (t_SplitValues[t_WildIndex].equals("?")) {
					// ? so move to next text char
					t_Index++;
					t_Chars = false;

				}
				else if (t_SplitValues[t_WildIndex].equals("*")) {
					// set any chars status
					t_Chars = true;
					if (t_WildIndex == t_SplitValues.length - 1) {
						t_Index = r_Keyword.length();
					}

				}
				else {
					// matching text token
					if (t_Chars) {
						// any chars then try to locate text token
						t_Index = r_Keyword.indexOf(t_SplitValues[t_WildIndex], t_Index);
						if (t_Index == -1) {
							// token not found
							break;
						}
						int repeat = r_Keyword.indexOf(t_SplitValues[t_WildIndex], t_Index + 1);
						if (repeat >= 0) {
							t_BackStack.push(new int[] {
								t_WildIndex,
								repeat
							});
						}
					}
					else {
						// matching from current position
						if (!r_Keyword.startsWith(t_SplitValues[t_WildIndex], t_Index)) {
							// couldnt match token
							break;
						}
					}

					// matched text token, move text index to end of matched token
					t_Index += t_SplitValues[t_WildIndex].length();
					t_Chars = false;
				}

				t_WildIndex++;
			}

			// full match
			if ((t_WildIndex == t_SplitValues.length) && (t_Index == r_Keyword.length())) {
				return true;
			}

		} while (t_BackStack.size() > 0);

		return false;
	}

	/**
	 * 将字符串按照'?'和'*'进行分解。<BR>
	 *
	 * Split a string into multi tokens by *'' and '?'.
	 *
	 * @param r_Text
	 * @return
	 */
	private static String[] splitOnTokens(String r_Text) {
		// used by wildcardMatch
		// package level so a unit test may run on this

		if ((r_Text.indexOf("?") == -1) && (r_Text.indexOf("*") == -1)) {
			return new String[] {
				r_Text
			};
		}

		char[] t_Array = r_Text.toCharArray();
		ArrayList t_List = new ArrayList();
		StringBuffer t_Buffer = new StringBuffer();
		for (int i = 0; i < t_Array.length; i++) {
			if ((t_Array[i] == '?') || (t_Array[i] == '*')) {
				if (t_Buffer.length() != 0) {
					t_List.add(t_Buffer.toString());
					t_Buffer.setLength(0);
				}
				if (t_Array[i] == '?') {
					t_List.add("?");
				}
				else if ((t_List.size() == 0) || ((i > 0) && (t_List.get(t_List.size() - 1).equals("*") == false))) {
					t_List.add("*");
				}
			}
			else {
				t_Buffer.append(t_Array[i]);
			}
		}
		if (t_Buffer.length() != 0) {
			t_List.add(t_Buffer.toString());
		}

		return (String[]) t_List.toArray(new String[0]);
	}

	/**
	 * 用来判断一个字符串是否在指定的字符串数组中。<BR>
	 *
	 * Used to judge whether the string array contains a specified string.<BR>
	 *
	 * @param r_Source
	 * @param r_Target
	 * @param r_CaseSensitive
	 * @return the the parameter of "r_Source" is in the string arry,return <code>true</code>.
	 */
	public static boolean isIn(String r_Source, String[] r_Target, boolean r_CaseSensitive) {
		for (int i = 0; i < r_Target.length; i++) {
			String t_Value = r_Target[i];
			if (r_CaseSensitive) {
				if (StringUtils.equals(r_Source, t_Value)) {
					return true;
				}
			} else {
				if (StringUtils.equalsIgnoreCase(r_Source, t_Value)) {
					return true;
				}
			}			
		}

		return false;
	}

	/**
	 * 用来判断一个字符串是否在指定的字符串数组中。<BR>
	 *
	 * Used to judge whether the string array contains a specified string.<BR>
	 *
	 * @param r_Source
	 * @param r_Target
	 * @return the the parameter of "r_Source" is in the string arry,return <code>true</code>.
	 */
	public static boolean isIn(String r_Source, Collection r_Target) {
		for (Iterator t_Iterator = r_Target.iterator(); t_Iterator.hasNext();) {
			String t_Value = (String) t_Iterator.next();
			if (StringUtils.equalsIgnoreCase(r_Source, t_Value)) {
				return true;
			}
		}

		return false;
	}

	/**以xml结点结尾形式返回
	 * 如:'<\/'+ targetName + '>'
	 * @param name
	 * @return
	 */
	public static String targetEndStyle(String name) {
		return "</" + name + ">";
	}

	/**
	 * 返回被赋值样式
	 * 如:="value"
	 * @param value
	 * @return
	 */
	public static String valueToSetStyle(String value) {
		if (value == null) {
			value = "";
		}
		return "=\"" + value + "\"";
	}
	
	/**
	 * 判断是否相等，null和""都认为相等
	 * 
	 * @param s1 字符串1
	 * @param s2 字符串2
	 * @return true:相等
	 */
	public static boolean equal(String s1, String s2) {
		if (s1 == s2) {
			return true;
		}
		
		if (s1 == null) {
			s1 = "";
		}
		
		if (s2 == null) {
			s2 = "";
		}
		
		s1 = s1.trim();
		s2 = s2.trim();
		
		if (s1.equals(s2)) {
			return true;
		}
		return false;
	}
	
	/**
	 * 连接对象的字符串
	 * 
	 * @param args 被连接的对象
	 * @return 字符串
	 */
	public static String concat(Object... args) {
		StringBuffer buf = new StringBuffer();
		for (Object arg : args) {
			buf.append(arg);
		}
		return buf.toString();
	}
	
	/**
	 * 格式化字符串
	 * 
	 * @param s 被格式化的字符串
	 * @param params 格式化参数
	 * @return 格式化后的字符串
	 */
	public static String format(String s, Object[] params) {
		String message = s;
		if (message == null) {
			return "";
		}
		if (params != null && params.length > 0) {
			message = new MessageFormat(message).format(params);
		}
		return message;
		
	}

	/**
	 * Test if the given String starts with the specified prefix,
	 * ignoring upper/lower case.
	 * @param str the String to check
	 * @param prefix the prefix to look for
	 * @see java.lang.String#startsWith
	 */
	public static boolean startsWithIgnoreCase(String str, String prefix) {
		if (str == null || prefix == null) {
			return false;
		}
		if (str.startsWith(prefix)) {
			return true;
		}
		if (str.length() < prefix.length()) {
			return false;
		}
		String lcStr = str.substring(0, prefix.length()).toLowerCase();
		String lcPrefix = prefix.toLowerCase();
		return lcStr.equals(lcPrefix);
	}

//	/**
//	 * Tests whether or not a given path matches a given pattern.
//	 *
//	 * @param pattern The pattern to match against. Must not be
//	 *                <code>null</code>.
//	 * @param str     The path to match, as a String. Must not be
//	 *                <code>null</code>.
//	 * @param isCaseSensitive Whether or not matching should be performed
//	 *                        case sensitively.
//	 *
//	 * @return <code>true</code> if the pattern matches against the string,
//	 *         or <code>false</code> otherwise.
//	 */
//	public static boolean matchPath(String pattern, String str,
//	                                boolean isCaseSensitive) {
//	    String[] patDirs = StringUtil.tokenizePathAsArray(pattern);
//	    String[] strDirs = StringUtil.tokenizePathAsArray(str);
//
//	    int patIdxStart = 0;
//	    int patIdxEnd = patDirs.length - 1;
//	    int strIdxStart = 0;
//	    int strIdxEnd = strDirs.length - 1;
//
//	    // up to first '**'
//	    while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
//	        String patDir = patDirs[patIdxStart];
//	        if (patDir.equals("**")) {
//	            break;
//	        }
//	        if (!StringUtil.match(patDir, strDirs[strIdxStart], isCaseSensitive)) {
//	            patDirs = null;
//	            strDirs = null;
//	            return false;
//	        }
//	        patIdxStart++;
//	        strIdxStart++;
//	    }
//	    if (strIdxStart > strIdxEnd) {
//	        // String is exhausted
//	        for (int i = patIdxStart; i <= patIdxEnd; i++) {
//	            if (!patDirs[i].equals("**")) {
//	                patDirs = null;
//	                strDirs = null;
//	                return false;
//	            }
//	        }
//	        return true;
//	    } else {
//	        if (patIdxStart > patIdxEnd) {
//	            // String not exhausted, but pattern is. Failure.
//	            patDirs = null;
//	            strDirs = null;
//	            return false;
//	        }
//	    }
//
//	    // up to last '**'
//	    while (patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd) {
//	        String patDir = patDirs[patIdxEnd];
//	        if (patDir.equals("**")) {
//	            break;
//	        }
//	        if (!StringUtil.match(patDir, strDirs[strIdxEnd], isCaseSensitive)) {
//	            patDirs = null;
//	            strDirs = null;
//	            return false;
//	        }
//	        patIdxEnd--;
//	        strIdxEnd--;
//	    }
//	    if (strIdxStart > strIdxEnd) {
//	        // String is exhausted
//	        for (int i = patIdxStart; i <= patIdxEnd; i++) {
//	            if (!patDirs[i].equals("**")) {
//	                patDirs = null;
//	                strDirs = null;
//	                return false;
//	            }
//	        }
//	        return true;
//	    }
//
//	    while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
//	        int patIdxTmp = -1;
//	        for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
//	            if (patDirs[i].equals("**")) {
//	                patIdxTmp = i;
//	                break;
//	            }
//	        }
//	        if (patIdxTmp == patIdxStart + 1) {
//	            // '**/**' situation, so skip one
//	            patIdxStart++;
//	            continue;
//	        }
//	        // Find the pattern between padIdxStart & padIdxTmp in str between
//	        // strIdxStart & strIdxEnd
//	        int patLength = (patIdxTmp - patIdxStart - 1);
//	        int strLength = (strIdxEnd - strIdxStart + 1);
//	        int foundIdx = -1;
//	        strLoop:
//	                    for (int i = 0; i <= strLength - patLength; i++) {
//	                        for (int j = 0; j < patLength; j++) {
//	                            String subPat = patDirs[patIdxStart + j + 1];
//	                            String subStr = strDirs[strIdxStart + i + j];
//	                            if (!StringUtil.match(subPat, subStr, isCaseSensitive)) {
//	                                continue strLoop;
//	                            }
//	                        }
//
//	                        foundIdx = strIdxStart + i;
//	                        break;
//	                    }
//
//	        if (foundIdx == -1) {
//	            patDirs = null;
//	            strDirs = null;
//	            return false;
//	        }
//
//	        patIdxStart = patIdxTmp;
//	        strIdxStart = foundIdx + patLength;
//	    }
//
//	    for (int i = patIdxStart; i <= patIdxEnd; i++) {
//	        if (!patDirs[i].equals("**")) {
//	            patDirs = null;
//	            strDirs = null;
//	            return false;
//	        }
//	    }
//
//	    return true;
//	}
//
//	/**
//	 * Tests whether or not a given path matches a given pattern.
//	 *
//	 * @param pattern The pattern to match against. Must not be
//	 *                <code>null</code>.
//	 * @param str     The path to match, as a String. Must not be
//	 *                <code>null</code>.
//	 *
//	 * @return <code>true</code> if the pattern matches against the string,
//	 *         or <code>false</code> otherwise.
//	 */
//	public static boolean matchPath(String pattern, String str) {
//	    return matchPath(pattern, str, true);
//	}
//
//	/**
//	 * Tests whether or not a string matches against a pattern.
//	 * The pattern may contain two special characters:<br>
//	 * '*' means zero or more characters<br>
//	 * '?' means one and only one character
//	 *
//	 * @param pattern The pattern to match against.
//	 *                Must not be <code>null</code>.
//	 * @param str     The string which must be matched against the pattern.
//	 *                Must not be <code>null</code>.
//	 *
//	 * @return <code>true</code> if the string matches against the pattern,
//	 *         or <code>false</code> otherwise.
//	 */
//	public static boolean match(String pattern, String str) {
//	    return StringUtil.match(pattern, str, true);
//	}
//
//	/**
//	 * Tests whether or not a string matches against a pattern.
//	 * The pattern may contain two special characters:<br>
//	 * '*' means zero or more characters<br>
//	 * '?' means one and only one character
//	 *
//	 * @param pattern The pattern to match against.
//	 *                Must not be <code>null</code>.
//	 * @param str     The string which must be matched against the pattern.
//	 *                Must not be <code>null</code>.
//	 * @param isCaseSensitive Whether or not matching should be performed
//	 *                        case sensitively.
//	 *
//	 *
//	 * @return <code>true</code> if the string matches against the pattern,
//	 *         or <code>false</code> otherwise.
//	 */
//	public static boolean match(String pattern, String str,
//	                            boolean isCaseSensitive) {
//	    char[] patArr = pattern.toCharArray();
//	    char[] strArr = str.toCharArray();
//	    int patIdxStart = 0;
//	    int patIdxEnd = patArr.length - 1;
//	    int strIdxStart = 0;
//	    int strIdxEnd = strArr.length - 1;
//	    char ch;
//
//	    boolean containsStar = false;
//	    for (int i = 0; i < patArr.length; i++) {
//	        if (patArr[i] == '*') {
//	            containsStar = true;
//	            break;
//	        }
//	    }
//
//	    if (!containsStar) {
//	        // No '*'s, so we make a shortcut
//	        if (patIdxEnd != strIdxEnd) {
//	            return false; // Pattern and string do not have the same size
//	        }
//	        for (int i = 0; i <= patIdxEnd; i++) {
//	            ch = patArr[i];
//	            if (ch != '?') {
//	                if (isCaseSensitive && ch != strArr[i]) {
//	                    return false; // Character mismatch
//	                }
//	                if (!isCaseSensitive && Character.toUpperCase(ch)
//	                        != Character.toUpperCase(strArr[i])) {
//	                    return false;  // Character mismatch
//	                }
//	            }
//	        }
//	        return true; // String matches against pattern
//	    }
//
//	    if (patIdxEnd == 0) {
//	        return true; // Pattern contains only '*', which matches anything
//	    }
//
//	    // Process characters before first star
//	    while ((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {
//	        if (ch != '?') {
//	            if (isCaseSensitive && ch != strArr[strIdxStart]) {
//	                return false; // Character mismatch
//	            }
//	            if (!isCaseSensitive && Character.toUpperCase(ch)
//	                    != Character.toUpperCase(strArr[strIdxStart])) {
//	                return false; // Character mismatch
//	            }
//	        }
//	        patIdxStart++;
//	        strIdxStart++;
//	    }
//	    if (strIdxStart > strIdxEnd) {
//	        // All characters in the string are used. Check if only '*'s are
//	        // left in the pattern. If so, we succeeded. Otherwise failure.
//	        for (int i = patIdxStart; i <= patIdxEnd; i++) {
//	            if (patArr[i] != '*') {
//	                return false;
//	            }
//	        }
//	        return true;
//	    }
//
//	    // Process characters after last star
//	    while ((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {
//	        if (ch != '?') {
//	            if (isCaseSensitive && ch != strArr[strIdxEnd]) {
//	                return false; // Character mismatch
//	            }
//	            if (!isCaseSensitive && Character.toUpperCase(ch)
//	                    != Character.toUpperCase(strArr[strIdxEnd])) {
//	                return false; // Character mismatch
//	            }
//	        }
//	        patIdxEnd--;
//	        strIdxEnd--;
//	    }
//	    if (strIdxStart > strIdxEnd) {
//	        // All characters in the string are used. Check if only '*'s are
//	        // left in the pattern. If so, we succeeded. Otherwise failure.
//	        for (int i = patIdxStart; i <= patIdxEnd; i++) {
//	            if (patArr[i] != '*') {
//	                return false;
//	            }
//	        }
//	        return true;
//	    }
//
//	    // process pattern between stars. padIdxStart and patIdxEnd point
//	    // always to a '*'.
//	    while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
//	        int patIdxTmp = -1;
//	        for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
//	            if (patArr[i] == '*') {
//	                patIdxTmp = i;
//	                break;
//	            }
//	        }
//	        if (patIdxTmp == patIdxStart + 1) {
//	            // Two stars next to each other, skip the first one.
//	            patIdxStart++;
//	            continue;
//	        }
//	        // Find the pattern between padIdxStart & padIdxTmp in str between
//	        // strIdxStart & strIdxEnd
//	        int patLength = (patIdxTmp - patIdxStart - 1);
//	        int strLength = (strIdxEnd - strIdxStart + 1);
//	        int foundIdx = -1;
//	        strLoop:
//	        for (int i = 0; i <= strLength - patLength; i++) {
//	            for (int j = 0; j < patLength; j++) {
//	                ch = patArr[patIdxStart + j + 1];
//	                if (ch != '?') {
//	                    if (isCaseSensitive && ch != strArr[strIdxStart + i
//	                            + j]) {
//	                        continue strLoop;
//	                    }
//	                    if (!isCaseSensitive
//	                        && Character.toUpperCase(ch)
//	                            != Character.toUpperCase(strArr[strIdxStart + i + j])) {
//	                        continue strLoop;
//	                    }
//	                }
//	            }
//
//	            foundIdx = strIdxStart + i;
//	            break;
//	        }
//
//	        if (foundIdx == -1) {
//	            return false;
//	        }
//
//	        patIdxStart = patIdxTmp;
//	        strIdxStart = foundIdx + patLength;
//	    }
//
//	    // All characters in the string are used. Check if only '*'s are left
//	    // in the pattern. If so, we succeeded. Otherwise failure.
//	    for (int i = patIdxStart; i <= patIdxEnd; i++) {
//	        if (patArr[i] != '*') {
//	            return false;
//	        }
//	    }
//	    return true;
//	}

//	/**
//	 * Same as {@link SelectorUtil#tokenizePath tokenizePath} but hopefully faster.
//	 */
//	public static String[] tokenizePathAsArray(String path) {
//	    String root = null;
//	    if (FilenameUtil.isAbsolutePath(path)) {
//	        String[] s = StringUtil.dissect(path);
//	        root = s[0];
//	        path = s[1];
//	    }
//	    char sep = File.separatorChar;
//	    int start = 0;
//	    int len = path.length();
//	    int count = 0;
//	    for (int pos = 0; pos < len; pos++) {
//	        if (path.charAt(pos) == sep) {
//	            if (pos != start) {
//	                count++;
//	            }
//	            start = pos + 1;
//	        }
//	    }
//	    if (len != start) {
//	        count++;
//	    }
//	    String[] l = new String[count + ((root == null) ? 0 : 1)];
//
//	    if (root != null) {
//	        l[0] = root;
//	        count = 1;
//	    } else {
//	        count = 0;
//	    }
//	    start = 0;
//	    for (int pos = 0; pos < len; pos++) {
//	        if (path.charAt(pos) == sep) {
//	            if (pos != start) {
//	                String tok = path.substring(start, pos);
//	                l[count++] = tok;
//	            }
//	            start = pos + 1;
//	        }
//	    }
//	    if (len != start) {
//	        String tok = path.substring(start);
//	        l[count/*++*/] = tok;
//	    }
//	    return l;
//	}

//	/**
//	 * Dissect the specified absolute path.
//	 * @param path the path to dissect.
//	 * @return String[] {root, remaining path}.
//	 * @throws java.lang.NullPointerException if path is null.
//	 */
//	public static String[] dissect(String path) {
//	    char sep = File.separatorChar;
//	    path = path.replace('/', sep).replace('\\', sep);
//
//	    // make sure we are dealing with an absolute path
//	    if (!FilenameUtil.isAbsolutePath(path)) {
//	        throw new IllegalArgumentException(path + " is not an absolute path");
//	    }
//	    String root = null;
//	    int colon = path.indexOf(':');
//	    if (colon > 0 && (FilenameUtil.onDos || FilenameUtil.onNetWare)) {
//
//	        int next = colon + 1;
//	        root = path.substring(0, next).toUpperCase();
//	        char[] ca = path.toCharArray();
//	        root += sep;
//	        //remove the initial separator; the root has it.
//	        next = (ca[next] == sep) ? next + 1 : next;
//
//	        StringBuffer sbPath = new StringBuffer();
//	        // Eliminate consecutive slashes after the drive spec:
//	        for (int i = next; i < ca.length; i++) {
//	            if (ca[i] != sep || ca[i - 1] != sep) {
//	                sbPath.append(ca[i]);
//	            }
//	        }
//	        path = sbPath.toString();
//	    } else if (path.length() > 1 && path.charAt(1) == sep) {
//	        // UNC drive
//	        int nextsep = path.indexOf(sep, 2);
//	        nextsep = path.indexOf(sep, nextsep + 1);
//	        root = (nextsep > 2) ? path.substring(0, nextsep + 1) : path;
//	        path = path.substring(root.length());
//	    } else {
//	        root = File.separator;
//	        path = path.substring(1);
//	    }
//	    return new String[] {root, path};
//	}

}